import math
import matplotlib.pyplot as plt
import numpy as np

plt.close('all')


def Affiche(image):
    plt.figure()
    plt.imshow(image)
    plt.axis('off')
    plt.show()
    plt.pause(0.00001)

## 3-1 - Algorithme KNN - Reconnaissance de panneaux

# Question 1
def Distance_uv(u,v):
    dist = 0
    for i in range(len(u)):
        dist = dist + (float(u[i])-float(v[i]))**2
    return math.sqrt(dist)

# Question 2
def Distance(u,Lv):
    distances = []
    for i,v in enumerate(Lv):
        distances.append([Distance_uv(u,v),i])
    return distances

# Question 3
def Proches(u,Lv,k):
    # Récupère les distances (u,vi)
    distances_uvi = Distance(u,Lv)

    # Tri des distances
    distances_uvi.sort()

    return [distances_uvi[i] for i in range(k)]

# Question 4
# ex : Lecture("Sources\\0\\0.bmp")
def Lecture(Chemin):
    arr = plt.imread(Chemin)
    return arr

# Question 5
def Analyse(Image):
    L_RGB = []

    nl,nc,_ = Image.shape
    for ligne in range(nl):
        for col in range(nc):
            for i in range(3):
                L_RGB.append(float(Image[ligne,col,i]))
    return L_RGB

# Question 6
def Analyse_Globale(L_Chemin):
    Liste_RGB = []
    for i, chemin in enumerate(L_Chemin):
        print("Apprentissage image ",i," sur ", len(L_Chemin))
        Liste_RGB.append(Analyse(Lecture(chemin)))
    return Liste_RGB

# Question 7
Dossiers = [0, 1, 2, 3, 4, 5, 6, 7]
Nb_Images_Dossiers = [5, 5, 5, 5, 5, 5, 5, 5]
Liste_Chemin = []
Liste_Dossier = []
Liste_Num = []
for i,num_dossier in enumerate(Dossiers):
    nb_images = Nb_Images_Dossiers[i]

    for n in range(nb_images):
        Liste_Dossier.append(num_dossier)
        Liste_Num.append(n)
        Liste_Chemin.append("Sources\\" + str(num_dossier) + "\\" + str(n) + ".bmp")

# Question 8
Donnees = []
L_RGB = Analyse_Globale(Liste_Chemin)

# Question 9
src_image = "Recherche\\31.bmp"
arr_img = plt.imread(src_image)
Affiche(arr_img)
L_RGB_image = Analyse(arr_img)

# Question 10
proches = Proches(L_RGB_image, L_RGB, 5)
Resultat_Ind = [proches[i][1] for i in range(len(proches))]
Resultat_Dossiers = [Liste_Dossier[i] for i in [Resultat_Ind[j] for j in range(len(Resultat_Ind))]]
Resultat_Num = [Liste_Num[i] for i in [Resultat_Ind[j] for j in range(len(Resultat_Ind))]]
print("Dossiers: ",Resultat_Dossiers)
print("Num: ",Resultat_Num)

# Question 11
def Max_Occurences(L):
    nb_val = {i:0 for i in L}
    for val in L:
        nb_val[val] = nb_val[val] + 1
    nb_max = max(nb_val.values())

    for cle in nb_val:
        if nb_val[cle] == nb_max:
            return cle

# Question 12
meilleur_dossier = Max_Occurences(Resultat_Dossiers)
print(meilleur_dossier)
num_image = Resultat_Num[Resultat_Dossiers.index(meilleur_dossier)]
Affiche(plt.imread("Sources\\" + str(meilleur_dossier) + "\\" + str(num_image)+".bmp"))

# Question 13
# M(1,0)=1 : On a trouvé une image donc=t le nom commence par 1 dans le dossier 0

# Question 14
LR = ['01', '11', '12', '21', '22', '31', '41', '42', '51', '52', '61', '71']

# Question 15
LCR = ["Recherche\\" + LR[i] + ".bmp" for i in range(len(LR))]

# Question 16
Donnees_R = Analyse_Globale(LCR)

# Question 17
def Resolution(DR,k):
    proches = Proches(DR, L_RGB, k)
    Resultat_Ind = [proches[i][1] for i in range(len(proches))]
    Resultat_Dossiers = [Liste_Dossier[i] for i in [Resultat_Ind[j] for j in range(len(Resultat_Ind))]]
    meilleur_dossier = Max_Occurences(Resultat_Dossiers)
    return meilleur_dossier

# Question 18
def Etude(k):
    M = np.zeros((len(Dossiers),len(Dossiers)),dtype=int)

    for i,DR in enumerate(Donnees_R):
        dossier = Resolution(DR,k)
        M[int(LR[i][0]),dossier] = M[int(LR[i][0]),dossier] + 1
    return M

# Question 19
# Pour k=1 a 5,
for i in range(1,6):
    print("\nk = ",i)
    print(Etude(i))



u=[1,3,5]
v1=[1,2,3]
v2=[2,4,6]
v3=[1,3,5]
Lv=[v1,v2,v3]
arr = Lecture("Sources\\0\\0.bmp")

chemins = ["Sources\\0\\"+str(i)+".bmp" for i in range(5)]
